9 typedef unsigned int uint32
;
11 #define forsn(i, s, n) for (uint32 i = (s); i < (n); i++)
12 #define forn(i, n) forsn (i, 0, n)
13 #define fordn(i, n) for (uint32 i = (n); i-- > 0;)
16 // Represents a number in 0 <= n < 10 ** 128
18 #define BigInt_NDIGITS 16
19 #define BigInt_BASE 100000000
22 BigInt() : _digits(BigInt_NDIGITS
, 0) {}
24 BigInt(uint32 n
) : _digits(BigInt_NDIGITS
, 0) {
25 assert(n
< BigInt_BASE
);
31 BigInt(const string
& s
) : _digits(BigInt_NDIGITS
, 0) {
36 assert('0' <= s
[i
] && s
[i
] <= '9');
37 digit
+= pow
* (s
[i
] - '0');
40 if (pow
== BigInt_BASE
) {
46 assert(j
< BigInt_NDIGITS
|| digit
== 0);
47 if (j
< BigInt_NDIGITS
) {
53 BigInt
operator+(const BigInt
& n
) {
57 forn (i
, BigInt_NDIGITS
) {
58 const uint32 r
= _digits
[i
] + n
._digits
[i
] + carry
;
59 if (r
>= BigInt_BASE
) {
60 res
._digits
[i
] = r
% BigInt_BASE
;
61 assert(r
/ BigInt_BASE
== 1);
74 fordn (i
, BigInt_NDIGITS
) {
76 if (_digits
[i
] == 0) continue;
77 printf("%u", _digits
[i
]);
80 printf("%.8u", _digits
[i
]);
89 // Least significant digit first.
90 // Digits are in 0 <= d < BigInt_BASE
91 vector
<uint32
> _digits
;
94 #define print_bigint(x) (x).print()
96 typedef vector
<BigInt
> vBigInt
;
97 typedef vector
<vBigInt
> vvBigInt
;
98 BigInt
distinct_subsequences(const string
& x
, const string
& z
) {
99 vvBigInt
m(2, vBigInt(z
.size() + 1, BigInt(0)));
104 forsn (i
, 1, x
.size() + 1) {
105 forsn (j
, 1, z
.size() + 1) {
106 if (x
[i
- 1] == z
[j
- 1]) {
107 m
[row
][j
] = m
[!row
][j
] + m
[!row
][j
- 1];
109 m
[row
][j
] = m
[!row
][j
];
114 return m
[!row
][z
.size()];
123 void contar_substrings(string x
, string z
){
125 // Diccionario para poder acceder en O(1) a los prefijos que terminan en cierta letra
126 list
<Prefijo
*> diccionario
[26];
128 // Inicializamos el diccionario
131 diccionario
[i
] = list
<Prefijo
*>();
136 Prefijo
* anterior
= 0;
138 Idea: para guardar un prefijo me alcanza conocer cual era el prefijo anterior (una letra menos) y cual es su ultima letra
141 Prefijo
* aux
= new Prefijo
;
142 aux
->cantidad
= BigInt(0);
143 aux
-> previo
= anterior
;
144 diccionario
[*it
-97].push_front(aux
);
150 list
<Prefijo
*>::iterator it2
;
152 foreachin(it2
,(diccionario
[*it
-97])){
153 // Si es el prefijo de una sola letra, encontre uno mas
154 if((*it2
)->previo
== 0)(*it2
)->cantidad
=(*it2
)->cantidad
+ BigInt(1);
155 // Sino, tengo tantos como tenia mas la cantidad de prefijos de una letra menos, que ahora se completan
156 else (*it2
)->cantidad
= (*it2
)->cantidad
+ (*it2
)->previo
->cantidad
;
160 char ultimo
= *(--z
.end());
161 print_bigint((*(diccionario
[ultimo
- 97].begin()))->cantidad
);
165 list
<Prefijo
*>::iterator it2
;
166 Prefijo
* aux
= diccionario
[*it
-97].front();
167 diccionario
[*it
-97].pop_front();
173 int main(int argc
, char **argv
) {
180 } else if (argc
== 3) {
196 //print_bigint(distinct_subsequences(x, z));
197 contar_substrings(x
,z
);